package com.oracle.search.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.oracle.client.ESClientConfig;
import com.oracle.index.NewsIndex;
import com.oracle.pojo.News;
import com.oracle.pojo.dto.SearchNewsDTO;
import com.oracle.search.service.api.SearchServiceApi;
import com.oracle.vo.PageVo;
import com.oracle.vo.ResultEntity;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.omg.CORBA.INTERNAL;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class SearchServiceImpl implements SearchServiceApi {

    @Autowired
    private ESClientConfig eSClientConfig;

    @Override
    public ResultEntity<PageVo<News>> getNewsBySearch(SearchNewsDTO searchNewsDTO) {
        Integer pageSize = searchNewsDTO.getPageSize();
        Integer pageIndex = searchNewsDTO.getPageIndex();
        SearchRequest searchRequest=new SearchRequest();
        //指定索引
        searchRequest.indices("news");
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        //分页设置-----------------------------------
        searchSourceBuilder.size(pageSize);//一共显示的数据条数
        //计算开始数据位置
        Integer offSet = (pageIndex-1)*pageSize;
        System.out.println("offSet----------------------->"+offSet);
        searchSourceBuilder.from(offSet);//从第几条开始
        //-------------------------------------
        //高亮
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<b style='color:red'>");   //高亮设置
        highlightBuilder.postTags("</b>");
        searchSourceBuilder.highlighter(highlightBuilder);
        QueryBuilder queryBuilder = this.queryBuilders(searchNewsDTO);
        System.out.println("----------------queryBuilder---------->"+queryBuilder);
        searchSourceBuilder.query(queryBuilder);
        //指定DSL
        searchRequest.source(searchSourceBuilder);
        //定义集合
        List<News> list = null;
        //定义PageVo对象
        PageVo<News> pageVo = new PageVo<News>();
        try {
            SearchResponse response = this.eSClientConfig.esRestClient().search(searchRequest, this.eSClientConfig.COMMON_OPTIONS);
            //结果分析获取
            SearchHits hits = response.getHits();
            SearchHit[] hitsHits = hits.getHits();
            list=new ArrayList<>();
            for (SearchHit hit : hitsHits) {
                String sourceAsString = hit.getSourceAsString();
                NewsIndex newsIndex=JSONObject.parseObject(sourceAsString,NewsIndex.class);
                HighlightField highlightField=hit.getHighlightFields().get("title");
                String highlinghFiled=null;
                if(highlightField!=null){
                    highlinghFiled=highlightField.getFragments()[0].string();
                    newsIndex.setTitle(highlinghFiled);
                }
                //定义News对象把NewsIndex新闻索引对象中的数据传递给News对象，返回集合
                News news = new News();
                BeanUtils.copyProperties(newsIndex,news);
                news.setId(Integer.parseInt(newsIndex.getId()));
                list.add(news);
            }
            System.out.println("-------sizeList----->"+list.size());
            System.out.println("当前页pageIndex---------->"+pageIndex);
            System.out.println("每页显示数量pageSize------->"+pageSize);
            TotalHits totalHits = response.getHits().getTotalHits();
            Integer total = Integer.parseInt(totalHits.value + "");
            System.out.println("总数据量totalData----------->"+totalHits.value);

            pageVo.setPageIndex(pageIndex);
            pageVo.setpageSize(pageSize);
            pageVo.setDataTotal(total);
            pageVo.setPageTotal(total%pageSize==0?total/pageSize:total/pageSize+1);
            System.out.println("总页数totalPage---------->"+pageVo.getPageTotal());
            pageVo.setObjList(list);
           return new ResultEntity(ResultEntity.CODE_SUCCESS,ResultEntity.MSG_SUCCESS,pageVo);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResultEntity(ResultEntity.CODE_SUCCESS,ResultEntity.MSG_SUCCESS,pageVo);
    }

    /**
     * 编写一个构建器，根据构建器进行构建查询
     * @param searchNewsDTO
     * @return
     */
    public QueryBuilder queryBuilders(SearchNewsDTO searchNewsDTO){
        if(searchNewsDTO==null){
            MatchAllQueryBuilder matchAllQueryBuilder=QueryBuilders.matchAllQuery();
            return matchAllQueryBuilder;
        }
        BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
        List<MatchQueryBuilder> list=new ArrayList<>();
        if(searchNewsDTO.getTitle()!=null&&!"".equals(searchNewsDTO.getTitle())){
            MatchQueryBuilder titleMatchQueryBuilder= QueryBuilders.matchQuery("title",searchNewsDTO.getTitle());
            list.add(titleMatchQueryBuilder);
        }
        if(searchNewsDTO.getAuthor()!=null&&!"".equals(searchNewsDTO.getAuthor())){
            MatchQueryBuilder authorMatchQueryBuilder=QueryBuilders.matchQuery("author",searchNewsDTO.getAuthor());
            list.add(authorMatchQueryBuilder);
        }
        if (searchNewsDTO.getCategory()!=null&&!"".equals(searchNewsDTO.getCategory())) {
            MatchQueryBuilder categoryMatchQueryBuilder=QueryBuilders.matchQuery("category",searchNewsDTO.getCategory());
            list.add(categoryMatchQueryBuilder);
        }
        boolQueryBuilder.must().addAll(list);
        return boolQueryBuilder;
    }

}
